﻿package com.atn.edamame
{	
	import flash.text.TextField;
	import flash.utils.*;
	import flash.net.*; 
	import flash.events.*;
    import flash.display.*;
	
	import mx.core.UIComponent;
	import mx.controls.TextInput;
	import mx.containers.Canvas;
	
	import com.atn.edamame.*;
	import com.atn.edamame.googlews.*;
	import com.atn.edamame.tools.*;
	
	import org.libspark.asreflect.*;

	public class EdamameEditor extends Canvas
    {
            private var rdc:RDC;
            private var objects:Array;	
			public var drag:Boolean;
			public var edamameID:int;
			[Bindable]
			public var title:String;
			[Bindable]
			public var comment:String;
			public var loading:Sprite;
			[Embed(source='../../../loading.swf')]
			private var LoadingSWF:Class;
			private var edamameToolFactory:EdamameToolFactory = EdamameToolFactory.getInstance();
            public function EdamameEditor()
            {
				drag = false;
				edamameID = 6;
                RDC.SUBDIVISION_THRESHOLD = 8;
				objects = [];
				rdc = new RDC(collide); 
				this.height = 2000;
				this.graphics.beginFill(0x333333, 1);
				this.graphics.drawRect(0, 0, 30, 2000);
				this.graphics.drawRect(0, 1800, this.width, 2000);
				this.graphics.endFill();
                this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
            }
			
			private function startLoading():void
			{
				loading = new Sprite();
				loading.x = 0;
				loading.y = 0;
			
				var back:Sprite = new Sprite();
				back.graphics.beginFill(0x999999, 0.5);
				back.graphics.drawRect(0, 0,root.stage.stageWidth, root.stage.stageHeight);
				back.graphics.endFill();

				loading.addChild(back);
				
				var mc:MovieClip = new LoadingSWF() as MovieClip;
				mc.x = root.stage.stageWidth/2 - mc.width/2;
				mc.y = root.stage.stageHeight/2 - mc.height/2;
				loading.addChild(mc);
				
				var lastIndex:int = root.stage.numChildren - 1;
				root.stage.addChild(loading);
				
			}
			
			private function stopLoading():void
			{
				var lastIndex:int = root.stage.numChildren - 1;
				root.stage.removeChildAt(lastIndex);
			}
			
            private function enterFrameHandler(event:Event):void
            {
				var i:int = 0;
				if ( drag == true )
				{
					return ;
				}
                for each (var c:EdamameObject in objects) {
					try {
						c.enterFrame();
					}catch (e:Error) {
						objects.splice(i, 1);
					}
					i++;
                }
                rdc.recursiveClustering(objects, 1, 0);
            }

            public function reset():void
            {
                for each (var c:EdamameObject in objects) {
					try {
						c.destroy();
					}catch (e:Error) {
						
					}
                }
				objects = [];
            }
			
            private function collide(a:EdamameObject, b:EdamameObject):void
            {
                if (a.hitTestObject(b))
                {
					try{
						a.collide(b);
						b.collide(a);
					}catch (e:Error) {
						
					}
				}
            }

			public function addEdamameObject(e:EdamameObject):void
			{
				e.edamameParent = this;
				e.init();
				addChild(e);
				objects[objects.length] = e;
			}

			protected function onLoadComplete(results:Object) :void {
					var edamame:XML = new XML(results);
					reset();
					title = edamame.title;
					comment = edamame.comment;
					for (var i:Object in edamame.EdamameControl)
					{	
						var clazz:Class = flash.utils.getDefinitionByName(edamame.EdamameControl[i].className) as Class;
						var gcon:* = new clazz();
						gcon.x = edamame.EdamameControl[i].x;
						gcon.y = edamame.EdamameControl[i].y;
						gcon.description = edamame.EdamameControl[i].description;
						for (var j:Object in edamame.EdamameControl[i].properties.property)
						{
							gcon[edamame.EdamameControl[i].properties.property.name] = edamame.EdamameControl[i].properties.property.value;
						}
						addEdamameObject(gcon);
					}
					stopLoading();
					//flash.utils.getDefinitionByName();
			}
			
			protected function onSaveComplete(results:Object) :void {
				trace("ok" + (results as String));
				stopLoading();
			}
			protected function onFail(results:Object) :void
			{
				trace("ng" + (results as String));
				stopLoading();
			}
			
			public function load():void {
				var responder:Responder = new Responder(onLoadComplete, onFail);
				GConnection.getInstance().getConnection().call("loadEdamame", responder, edamameID);
				startLoading();
			}
			
			public function save():void {
				startLoading();
				var edamame:XML = createEdamame();
				trace(edamame.toString());
				var responder:Responder = new Responder(onSaveComplete, onFail);
				GConnection.getInstance().getConnection().call("saveEdamame", responder, edamameID,title,comment,edamame.toString());
			}
			
			public function run():void
			{
				var grun:EdamameRunner = new EdamameRunner();
				grun.setEdamame(createEdamame());
			}
			
			public function createEdamame():XML
			{
				var edamame:XML = <Edamame/>;
				edamame.title = title;
				edamame.comment = comment;
				for each(var obj:EdamameObject in objects) {
					if(obj is EdamameControl && obj.deleted == false){
						edamame.appendChild(controlToXML(obj));
					}
				}
				return edamame;
			}
			
			//TODO create edamame class
			public function controlToXML(control:*):XML {
					var obj:XML = <EdamameControl/>;
					var type:Type = ASReflect.getTypeFrom(control);
					obj.className = type.qualifiedName;
					obj.properties = <properties/>;
					trace("" + obj.className);
					obj.x = control.x;
					obj.y = control.y;
					obj.width = control.width;
					obj.description = control.description;
					for each (var prop:Property in type.properties) {
						if (ASReflect.getType(prop.declaringClass).qualifiedName == type.qualifiedName) {
								var propObj:XML = <property/>;
								propObj.name = prop.name;
								propObj.type = prop.type;
								propObj.value =  prop.getValue(control);
								trace("\t" + propObj.name + "-" + propObj.value);
								obj.properties.appendChild(propObj);
						}
					}
					for each (var sClass:Class in type.superClasses) {
						if (sClass == EdamameControl) {
							break;
						}
						for each (var prop2:Property in type.properties) {
							if (prop.declaringClass == sClass) {
									var propObj2:XML = <property/>;
									propObj2.name = prop2.name;
									propObj2.type = prop2.type;
									//propObj2.value2 =  prop2.getValue(control);
									trace("\t" + propObj2.name + "-" + propObj2.value2);
									obj.properties.appendChild(propObj2);
							}
						}
					}
					return obj;
			}
			
        }
}